#!/usr/bin/env python
#
# Copyright 2009 Acumino - http://www.acumino.com/
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
Example usage:
>>> from registry import registry
"""
from google.appengine.ext import db
from google.appengine.api import users

class RegistrySetting(db.Expando):
	name = db.StringProperty(required=True)
	forced = db.BooleanProperty(required=True, default=False)
	user = db.UserProperty()
	#value = db.StringProperty(required=True)

class Registry(object):
	"""Provides methods to access the registry"""
	def __init__(self):
		pass
	
	def get(self, name, user=None):
		if user:
			if not users.is_current_user_admin():
				raise AssertionError("Non-admin cannot fetch other users' settings.")
		else:
			user = users.get_current_user()
		app_settings  = {True: [], False: []}
		user_settings = {True: [], False: []}

		# fetch global app settings
		q = db.Query(RegistrySetting).filter("user =", None).filter("name =", name).order("-forced")
		for r in q.fetch(1000):
			app_settings[r.forced].append(r.value)
			
		# if we found any settings forced by the app then return (only) them now
		if len(app_settings[True]) > 0:
			return app_settings[True]

		# fetch user-specific settings if logged on
		if (user):
			q = db.Query(RegistrySetting).filter("user =", user).filter("name =", name).order("-forced")
			for r in q.fetch(1000):
				app_settings[r.forced].append(r.value)

		# if we found any settings forced by the user then return (only) them now
		if len(user_settings[True]) > 0:
			return user_settings[True]
			
		# finally merge the user settings with the app settings
		results = []
		if len(app_settings[False])  > 0: results.append(app_settings[False])
		if len(user_settings[False]) > 0: results.append(user_settings[False])
		return results

	def set(self, name, value, user=None, forced=False):
		# only admins can set arbitrary users - all others default to themselves
		if not users.is_current_user_admin():
			current_user = users.get_current_user()
			if user and user != current_user:
				raise AssertionError("Non-admin users must restrict settings"+
				" to their own username.")
			else:
				user = current_user
	
		setting = RegistrySetting(
			name = name,
			user = user,
			forced = forced,
			value = value)
		setting.put()

#	def dump():
#		"""Dumps the registry as a hash"""

global registry
registry = Registry()
